/**
 * 解构赋值
 */

// 数组解构赋值==================================

// 本质上这种写法属于“模式匹配”，只要等号两边的模式相同，左边的变量就会被赋予对应的值-------------
// const arr = [100, 200, 300]
// const [foo, bar, baz] = arr
// console.log(foo, bar, baz)

// const [, , baz] = arr
// console.log(baz)

// const [foo, ...reset] = arr
// console.log(foo, reset)

// const [a, [b], c] = [1, [2, 3], 4, 5]
// console.log(a,b,c) // 1 2 4

// 事实上，只要某种数据结构具有Iterator接口，都可以采用数组形式的解构赋值----------------------
// function* fibs () {
//   let a = 1
//   while (true) {
//     yield a++
//   }
// }

// const [a, b, c, d] = fibs()
// console.log(a,b,c,d) // 1 2 3 4

// 默认值----------------------------------------------------------
// 一个数组成员不严格等于undefined，默认值是不会生效的
// const arr = [100, 200, 300]
// const [foo, bar, baz = 123, more = 'default value'] = arr
// console.log(bar, baz, more) // 200 300 default value

// 如果默认值是一个表达式，那这个表达式是惰性求值的，只有在用到的时候才会求值
// function f () {
//   console.log('run f')
// }
// const [x = f()] = [1] // f不执行
// const [x = f()] = [] // f执行

// 默认值可以引用解构赋值的其他变量，但该变量必须已经声明
// const [x = 1, y = x] = [2]
// console.log(x, y) // 2 2

// x能取到值，并不会执行x=y这一步，因此不会报错
// const [x = y, y = 1] = [2]
// console.log(x, y) // 2 1

// x取默认值时y未声明，因此报错
// const [x = y, y = 1] = []
// console.log(x, y) // ReferenceError: y is not defined


// 对象解构赋值==================================

// 对象的解构赋值的内部机制，是先找到同名属性，然后再赋给对应的变量。真正被赋值的是后者，而不是前者---------
// const obj = { name: 'zce', age: 18 }
// 属性和变量同名时可简写
// const { name } = obj
// console.log(name)

// const { name: objName } = obj
// console.log(objName)

// 解构可用于嵌套结构的对象
// const obj = {
//   p: [
//     'Hello',
//     {
//       y: 'World'
//     }
//   ]
// };

// const { p: [x, { y }] } = obj
// console.log(x, y) // Hello World

// 对象解构默认值-----------------------------------------
// const { name: objName = 'jerry', age } = { age: 18 }
// console.log(objName, age)


// 字符串解构赋值========================================
// 字符串被转换成了一个类似数组的对象
// const [a, b, c, d, e] = 'hello';
// const { length: len } = 'hello';
// console.log(a, b, c, d, e)
// console.log(len)


// 数值和布尔值解构赋值===================================
// 解构赋值时，如果等号右边是数值和布尔值，则会先转为对象。
// const { toString: s } = 123
// const { toString: s } = true

// 由于undefined和null无法转为对象，所以对它们进行解构赋值，都会报错


// 函数参数解构赋值========================================
// const add = ([x, y]) => x + y
// console.log(add([1, 2])) // 3

// const arr = [[1, 2], [3, 4]].map(([a, b]) => a + b)
// console.log(arr) // [3, 7]


